/*
 * @Author: zsdddz
 * @Date: 2024-04-21 00:40:59
 * @LastEditTime: 2024-05-30 10:05:21
 */


import { w3cwebsocket} from 'websocket';
import AQMsgDecoder from './AQMsgDecoder';
import AQMsgEncoder from './AQMsgEncoder';
import ByteBuffer from './codec/ByteBuffer'
import * as AQChatMSg from './protocol/AQChatMsgProtocol_pb';


const SERVER_HOST = import.meta.env.VITE_SOCKET_API;
var loopTimer:any = null;
/**
 * 邮件附件类型定义（与后端接口匹配）
 */
interface EmailAttachment {
  filename: string;       // 附件文件名
  content_type: string;   // 附件MIME类型（如 text/plain、image/png）
  content: string;        // 附件内容的Base64编码
}

/**
 * 邮件数据类型定义（与后端接口匹配）
 */
interface EmailData {
  from: string;                   // 发件人（格式："名称 <邮箱>" 或 "邮箱"）
  to: string[];                   // 收件人列表
  cc?: string[];                  // 抄送列表（可选）
  bcc?: string[];                 // 密送列表（可选）
  subject: string;                // 邮件主题
  text?: string;                  // 文本正文（可选）
  html?: string;                  // HTML正文（可选）
  attachments?: EmailAttachment[]; // 附件列表（可选）
}

/**
 * 将文件转换为Base64编码
 * @param file 要转换的文件对象
 * @returns Base64编码字符串（不含前缀）
 */
async function fileToBase64(file: File): Promise<string> {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => {
      if (typeof reader.result === 'string') {
        // 移除DataURL前缀（如 "data:text/plain;base64,"）
        const base64Content = reader.result.split(',')[1];
        if (base64Content) {
          resolve(base64Content);
        } else {
          reject(new Error('文件转换失败：无法提取Base64内容'));
        }
      } else {
        reject(new Error('文件转换失败：不支持的结果类型'));
      }
    };
    reader.onerror = () => reject(new Error('文件读取失败：' + reader.error?.message));
  });
}

/**
 * 发送邮件到指定API接口
 * @param emailData 邮件数据对象
 * @returns 服务器响应（包含邮件ID等信息）
 */
async function sendEmailToApi(emailData: EmailData): Promise<{ id: number; message: string }> {
  try {
    const response = await fetch('http://A.B.C.159:31080/api/messages/eml', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        // 如需跨域，可能需要添加额外头信息（如Authorization）
      },
      body: JSON.stringify(emailData),
    });

    if (!response.ok) {
      // 处理HTTP错误（如400、500等）
      const errorDetails = await response.text().catch(() => '未知错误');
      throw new Error(`请求失败（${response.status}）：${errorDetails}`);
    }

    const result = await response.json();
    // console.log(8888888888,result)
    return result;
  } catch (error) {
    console.error('发送邮件失败：', error);
    throw error; // 向上传递错误，便于调用方处理
  }
}
export default class AQSender {
    /**
    * 单例对象
    */
    private static instance: AQSender = new AQSender();

    /**
     * WebSocket
     */
    private webSocket: w3cwebsocket | null = null;

    /**
     * 消息编码器
     */
    private readonly msgEncoder: AQMsgEncoder = new AQMsgEncoder();

    /**
     * 消息解码器
     */
    private readonly msgDecoder: AQMsgDecoder = new AQMsgDecoder();

    /**
     * 私有化类默认构造器
     */
    private constructor() {
    }

    /**
     * 获取单例对象
     */
    static getInstance(): AQSender {
        return AQSender.instance;
    }

    /**
     * 连接服务器
     * 
     * @param funCallback 回调函数
     */
    connect(funCallback: () => void): void {
        let strURL = `${SERVER_HOST}`;
        console.log(`准备连接服务器, URL = ${strURL}`);

        let oWebSocket = new w3cwebsocket(strURL);
        oWebSocket.binaryType = "arraybuffer";

        // 连接服务器
        oWebSocket.onopen = (): void => {
            console.log(`已连接服务器, URL = ${strURL}`);
            this.webSocket = oWebSocket;
            
            if (null != funCallback) {
                funCallback();
            }
        }

        // 异常
        oWebSocket.onerror = (): void => {
            console.error(`连接异常, URL = ${strURL}`);
            this.webSocket = null;
        }

        // 断开服务器
        oWebSocket.onclose = (): void => {
            console.warn("服务器连接已关闭");
            this.webSocket = null;
            this.closeService()
        }

        // 收到消息
        oWebSocket.onmessage = (event)=> {
            if (null == event ||
                null == event.data) {
                return;
            }

            //收到的消息是一个字节数组
            let bytebuf = new ByteBuffer(event.data);

            //解包
            let byteBuffer = bytebuf.int32().short().unpack();
            //解析bodylen
            let bodyLen = byteBuffer[0];
            //解析command
            let msgCommand = byteBuffer[1];
            if (msgCommand < 0 || bodyLen <= 0) {
                console.error("从服务端收到无效的消息");
                return;
            }

            let unpack = bytebuf.byteArray(null, bodyLen).unpack();
            let msgBody = unpack[2];

            // 构建消息体
            let aqMsgBody = this.msgDecoder.decode(msgCommand, msgBody);

            if (null == aqMsgBody) {
                console.error(`构建消息体为空, msgCommand = ${msgCommand}`);
                return;
            }

            // console.log(`从服务端收到消息, msgCommand = ${msgCommand}`);

            // 处理消息
            this.onMsgReceived(msgCommand, aqMsgBody);
        }
    }

    /**
     * 心跳
     * @param userId
     */
    heartbeatLoop() {
        let loop = () =>{
            if(this.webSocket == null){
                console.error("[心跳失败]未连接")
                return;
            }
            console.log("send ping...")
            let pack = new AQChatMSg.default.HeartBeatCmd();
            pack.setPing("AQChat-PING");
            this.sendMsg(AQChatMSg.default.MsgCommand.HEART_BEAT_CMD,pack);
        }
        loopTimer = setInterval(loop, 3000);
    }

    /**
     * 心跳停止
     */
    heartbeatStop(){
        if(loopTimer) clearInterval(loopTimer);
    }

    /**
     * 发送消息
     * 
     * @param msgCommand 消息编号
     * @param msgBody 消息体
     */
    sendMsg(msgCommand: number, msgBody: any): void {
        if (msgCommand < 0 ||
            null == msgBody) {
            return;
        }

        if (null == this.webSocket) {
            console.error("WebSocket 尚未初始化");
            this.closeService();
            return;
        }

        let msgPack = this.msgEncoder.encode(msgCommand, msgBody);
        if (null == msgPack || msgPack.byteLength <= 0) {
            console.error(`字节数组为空, msgCommand = ${msgCommand}`);
            return;
        }

        // console.log(`发送消息, msgCommand = ${msgCommand}`);
        this.webSocket.send(msgPack);
    }

    /**
     * 当收到消息
     * 
     * @param msgCommand 消息编号
     * @param msgBody 消息体
     */
    onMsgReceived(msgCommand: number, msgBody: any): void {
        if (msgCommand < 0 ||
            null == msgBody) {
            return;
        }
    }

    closeService(){}

    close(){
        this.webSocket && this.webSocket.close();
    }
    async  sendTestEmail(msgBody: any) {
        try {
            // 示例1：简单文本邮件
            const simpleEmail: EmailData = {
            from: 'Heready Client <heready.client@coconet.cn>',
            to: ['l20@coconet.cn'],
            subject: "id: " + msgBody.getMsgid()+' : Heready Client请求L20',
            text: msgBody.getMsg(),
            };

            const simpleResult = await sendEmailToApi(simpleEmail);
            console.log('简单邮件发送成功，ID：', simpleResult.id);

            // 示例2：带HTML和附件的邮件
            // 假设页面中有一个id为"fileInput"的文件选择器
            const fileInput = document.getElementById('fileInput') as HTMLInputElement;
            const attachments: EmailAttachment[] = [];

            if (fileInput?.files && fileInput.files.length > 0) {
            // 处理第一个选中的文件作为附件
            const file = fileInput.files[0];
            const base64Content = await fileToBase64(file);
            
            attachments.push({
                filename: file.name,
                content_type: file.type || 'application/octet-stream', // 默认为二进制流
                content: base64Content
            });
            }

            const complexEmail: EmailData = {
            from: 'HTML邮件发送者 <html@example.com>',
            to: ['recipient@example.com'],
            cc: ['cc@example.com'],
            subject: '带HTML和附件的邮件测试',
            text: '这是文本 fallback（当HTML无法显示时）',
            html: '<h1>HTML邮件标题</h1><p>这是一封包含<span style="color: blue;">样式</span>的HTML邮件</p>',
            attachments: attachments.length > 0 ? attachments : undefined
            };

            const complexResult = await sendEmailToApi(complexEmail);
            console.log('复杂邮件发送成功，ID：', complexResult.id);

            return { simpleResult, complexResult };
        } catch (error) {
            console.error('示例发送失败：', error);
            throw error;
        }
    }

}
